package dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Example;

import entity.Activity;
import entity.BSCElement;
import entity.BSCGoal;
import entity.Organization;
import entity.Process;
import entity.StrategicPlan;
import util.HibernateUtil;
import vo.ProcessVO;

public class ProcessDAO {
	
	Map<String, Integer> mapaProcessCompleted;
	
	public List<ProcessVO> getProcess() {
		Session sessao = HibernateUtil.getSession();
		Criteria criterios = sessao.createCriteria(Process.class);
		
		Process p = new Process();
		p.setInitialActivity(true);
		
		criterios.add(Example.create(p));
		List<?> processes = criterios.list();
		List<ProcessVO> listProcess = new ArrayList<ProcessVO>();
				
		p = (Process) processes.get(0);
		
		while(true){			
			ProcessVO vo = new ProcessVO();
			vo.setId(p.getId());
			vo.setDescription(p.getDescription());
			vo.setName(p.getName());			
			vo.setActivities(new ArrayList<ProcessVO>());
			vo.setCode(p.getCode());
		
			if (p.getActivities().size() > 0){
				int i = 0;
				Activity a = p.getActivities().get(i);
				while(! a.isInitialActivity()){
					i++;
					a = p.getActivities().get(i);
				}
				
				while(true){
					ProcessVO avo = new ProcessVO();
					avo.setId(a.getId());
					avo.setDescription(a.getDescription());
					avo.setName(a.getName());
					avo.setCode(a.getCode());
					vo.getActivities().add(avo);
					
					if (a.getNextActivity() != null){
						avo.setNextProcessId(a.getNextActivity().getId());
						a = a.getNextActivity();
					}	
					else{
						break;
					}
				}
			}
			
			listProcess.add(vo);

			if (p.getNextActivity() != null){
				vo.setNextProcessId(p.getNextActivity().getId());
				p = (Process) sessao.load(Process.class, p.getNextActivity().getId());
			}				
			else{
				break;
			}
		}
		
		sessao.close();
		return listProcess;
	}
	
	public void verifyProcessCompleted(int strategicPlanId){
		int inicio, defineStrategicMembers, survey, definePerspectives, establishStrategicFoundations, defineMission, defineValues, establishVision,
				gatherIntelligencePlanning, analiseAmbiente, stakeholders, swot, formulateStrategy, createBSC, establishGoals, createStrategyMap,
				chooseGoalsMetrics, buildCauseEffectLinks, establishTargets, designateGoalsManagers, createTrackingRules, createProgramActions, 
				linkActionProcesses, plano;
		
		Session sessao = HibernateUtil.getSession();
		
		StrategicPlan sp = (StrategicPlan) sessao.load(StrategicPlan.class, strategicPlanId);
		Organization o = (Organization) sessao.load(Organization.class, sp.getOrganizacao().getId());
		
		mapaProcessCompleted = new HashMap<String, Integer>();

		defineStrategicMembers = 0;
		mapaProcessCompleted.put("defineStrategicMembers", defineStrategicMembers);
		
		survey = 0;
		if ((sp.getListGettingStartedSurvey() != null) && (sp.getListGettingStartedSurvey().size() > 0))
			survey = 2;
		mapaProcessCompleted.put("survey", survey);

		definePerspectives = 0;
		if ((sp.getListPerspectives() != null) && (sp.getListPerspectives().size() > 0))
			definePerspectives = 2;
		mapaProcessCompleted.put("definePerspectives", definePerspectives);
		
		inicio = 0;
		if ((defineStrategicMembers == 2) && (survey == 2) && (definePerspectives == 2))
			inicio = 2;
		else if ((defineStrategicMembers > 0) || (survey > 0) || (definePerspectives > 0))
			inicio = 1;		
		mapaProcessCompleted.put("inicio", inicio);
		
		defineMission = 0;
		if (! o.getMission().equalsIgnoreCase(""))
			defineMission = 2;		
		mapaProcessCompleted.put("defineMission", defineMission);
		
		defineValues = 0;
		if ((o.getOrganizationValuesList() != null) && (o.getOrganizationValuesList().size() > 0))
			defineValues = 2;
		mapaProcessCompleted.put("defineValues", defineValues);

		establishVision = 0;
		if (! o.getVision().equalsIgnoreCase(""))
			establishVision = 2;
		mapaProcessCompleted.put("establishVision", establishVision);
		
		establishStrategicFoundations = 0;
		if ((defineMission == 2) && (defineValues == 2) && (establishVision == 2))
			establishStrategicFoundations = 2;
		else if ((defineMission > 0) || (defineValues > 0) || (establishVision > 0))
			establishStrategicFoundations = 1;
		mapaProcessCompleted.put("establishStrategicFoundations", establishStrategicFoundations);
		
		analiseAmbiente = 0;
		mapaProcessCompleted.put("analiseAmbiente", analiseAmbiente);
		
		stakeholders = 0;
		mapaProcessCompleted.put("stakeholders", stakeholders);
		
		swot = 0;
		if (sp.getSwot() != null)
			swot = 2;
		mapaProcessCompleted.put("swot", swot);

		gatherIntelligencePlanning = 0;
		if ((analiseAmbiente == 2) && (stakeholders == 2) && (swot == 2))
			gatherIntelligencePlanning = 2;
		else if ((analiseAmbiente > 0) || (stakeholders > 0) || (swot > 0))
			gatherIntelligencePlanning = 1;
		mapaProcessCompleted.put("gatherIntelligencePlanning", gatherIntelligencePlanning);
		
		formulateStrategy = 0;
		mapaProcessCompleted.put("formulateStrategy", formulateStrategy);
		
		establishGoals = 0;
		if ((sp.getBsc() != null) && (sp.getBsc().getListBSCElement() != null) && (sp.getBsc().getListBSCElement().size() > 0)){
			for(BSCElement bsce:sp.getBsc().getListBSCElement()){
				if (bsce instanceof BSCGoal){
					establishGoals = 2;				
				}
				
				if (establishGoals == 2)
					break;
			}
		}
		mapaProcessCompleted.put("establishGoals", establishGoals);
		
		createStrategyMap = 0;
		mapaProcessCompleted.put("createStrategyMap", createStrategyMap);
		
		chooseGoalsMetrics = 0;
		mapaProcessCompleted.put("chooseGoalsMetrics", chooseGoalsMetrics);
		
		buildCauseEffectLinks = 0;
		mapaProcessCompleted.put("buildCauseEffectLinks", buildCauseEffectLinks);
		
		establishTargets = 0;
		mapaProcessCompleted.put("establishTargets", establishTargets);
		
		designateGoalsManagers = 0;
		mapaProcessCompleted.put("designateGoalsManagers", designateGoalsManagers);
		
		createTrackingRules = 0;
		mapaProcessCompleted.put("createTrackingRules", createTrackingRules);
		
		createBSC = 0;
		if ((establishGoals == 2) && (createStrategyMap == 2) && (chooseGoalsMetrics == 2) && (buildCauseEffectLinks == 2) && 
			(establishTargets == 2) && (designateGoalsManagers == 2) && (createTrackingRules == 2))
			createBSC = 2;
		else if ((establishGoals > 0) || (createStrategyMap > 0) || (chooseGoalsMetrics > 0) || (buildCauseEffectLinks > 0) || 
				(establishTargets > 0) || (designateGoalsManagers > 0) || (createTrackingRules > 0))
			createBSC = 1;
		mapaProcessCompleted.put("createBSC", createBSC);
		
		createProgramActions = 0;
		mapaProcessCompleted.put("createProgramActions", createProgramActions);
		
		linkActionProcesses = 0;
		mapaProcessCompleted.put("linkActionProcesses", linkActionProcesses);
		
		plano = 0;
		if ((inicio == 2) && (establishStrategicFoundations == 2) && (gatherIntelligencePlanning == 2) && (formulateStrategy == 2) && (createBSC == 2) &&
			(createProgramActions == 2) && (linkActionProcesses == 2))
			plano = 2;
		else if ((inicio > 0) || (establishStrategicFoundations > 0) || (gatherIntelligencePlanning > 0) || (formulateStrategy > 0) || (createBSC > 0) ||
				(createProgramActions > 0) || (linkActionProcesses > 0))
			plano = 1;
		mapaProcessCompleted.put("plano", plano);

		sessao.close();
	}
	
	public int processCompleted(String code){
		if (mapaProcessCompleted.containsKey(code)) 		
			return mapaProcessCompleted.get(code);
		else
			return 0;
	}
}
